"""
CREATE: 2018/5/26
AUTHOR:　HEHAHUTU
"""

from app.models.cloud.folder import DiskFolder, DiskFile
from flask_restful import Resource, reqparse, fields
from app.api import api
from f_lib.principal.auth import auth_token

from f_lib.code import Msg
from flask import g, make_response, Response
from f_lib.marshal_list import marshal
from settings import UPLOAD_PATH
from datetime import datetime
import os
import shutil
import zipfile
import urllib.parse
from f_lib.principal.safety import safety_strategy


class CreateFolder(Resource):
    folder_parse = reqparse.RequestParser()
    # folder_parse.add_argument('event', required=True, type=str)
    folder_parse.add_argument('name', required=True, type=str)
    folder_parse.add_argument('folder_path', required=True, type=str)

    @safety_strategy
    @auth_token()
    def post(self):
        user_id = g.user.id
        arg = self.folder_parse.parse_args()
        arg['user_id'] = user_id
        check_rep = DiskFolder.query_one(**arg)
        if check_rep:
            return Msg.failed_dict(5001)
        folder = DiskFolder.create(**arg)
        return Msg.success('ok', id=folder.id)


class UpdateFolder(Resource):
    parse = reqparse.RequestParser()
    parse.add_argument('name')
    parse.add_argument('id')

    @safety_strategy
    @auth_token()
    def post(self):
        arg = self.parse.parse_args()
        folder = DiskFolder.get_by_id(arg['id'])
        if folder:
            print(arg)
            folder.update(**arg)
            return Msg.success('ok')
        else:
            return Msg.failed_dict(1002)


class DeleteFolder(Resource):
    parse = reqparse.RequestParser()
    parse.add_argument('id', type=int, required=True)

    @safety_strategy
    @auth_token()
    def post(self):
        arg = self.parse.parse_args()
        arg['user_id'] = g.user.id
        folder = DiskFolder.query_one(**arg)
        if folder:
            folder.update(is_trash=1)
            return Msg.success('ok')
        else:
            return Msg.failed_dict(1002)


folder_fields = {
    'id': fields.Integer,
    'name': fields.String,
    'folder_path': fields.String,
    'group_id': fields.Integer,
    'create_time': fields.datetime,
    'type': fields.String
}
file_fields = {
    'id': fields.Integer,
    'name': fields.String,
    'group_id': fields.Integer,
    'folder_path': fields.String,
    'create_time': fields.datetime,
    'type': fields.String,
    'file_size': fields.Integer,
    'file_name': fields.String,
    'is_thumb': fields.Integer,
    'is_share': fields.Integer
}


# list_path_fields = {
#     'folder': fields.List(folder_fields),
#     'file': fields.List(file_fields)
# }


class ListPath(Resource):
    folder_parse = reqparse.RequestParser()
    folder_parse.add_argument('folder_path', required=True, type=str)
    field_folder = dict(
        id=int,
        floder_name=str,

    )

    @safety_strategy
    @auth_token()
    # @marshal_with(list_path_fields)
    def post(self):
        user_id = g.user.id
        arg = self.folder_parse.parse_args()
        arg['user_id'] = user_id
        arg['is_trash'] = 0

        # print(arg)
        if arg['folder_path'] == '/':
            folder = DiskFolder.query_many(**arg)
            file = DiskFile.query_many(is_topic=None, **arg)
            mf = marshal(folder_fields, folder)
            mi = marshal(file_fields, file)

        else:

            folder = DiskFolder.query_many(**arg)
            file = DiskFile.query_many(is_topic=None, **arg)
            mf = marshal(folder_fields, folder)
            mi = marshal(file_fields, file)
        paths = mf + mi
        return Msg.success(msg='ok', paths=paths)


class FolderGroupFiles(Resource):
    @safety_strategy
    @auth_token()
    def get(self, id=None):
        if id and isinstance(id, int):
            folder = DiskFolder.get_by_id(id)
            if folder:
                path = folder.folder_path + folder.name
                data = DiskFolder.query_group_path_files(path, g.user.id)
                save_path = os.path.join(UPLOAD_PATH, g.user.use_folder)
                data = list(data)

                all_path_list = [item[1] for item in data]
                if len(all_path_list) > 0:
                    zip_folder = os.path.join(save_path, datetime.now().strftime('%Y%m%d_%H%M%S'))
                    file_name = '{}.zip'.format(folder.name)
                    file_folder = os.path.join(zip_folder, file_name)

                    os.mkdir(zip_folder)
                    # os.mkdir(file_folder)
                    # for file_path in all_path_list:
                    #
                    #     shutil.copy(file_path, file_folder)
                    zips = zipfile.ZipFile(file_folder, 'w', zipfile.ZIP_DEFLATED)
                    fo = os.path.join(zip_folder, folder.name)

                    zips.write(zip_folder, folder.name)
                    for file in all_path_list:
                        zips.write(os.path.join(save_path, file), '/{}/{}'.format(folder.name, file))

                    def read_file(path):
                        with open(path, 'rb') as f:
                            while True:
                                da = f.read(1024 * 100)
                                if da:
                                    yield da
                                else:
                                    shutil.rmtree(zip_folder)
                                    return False

                    value = read_file(file_folder)
                    resp = Response(value)
                    # print(len(data))
                    name = urllib.parse.quote(file_name)

                    resp.headers["Content-Disposition"] = f"attachment; filename*=utf-8''{name}"
                    resp.headers["Content-Type"] = f"application/octet-stream; charset=utf-8"
                    resp.headers["Connection"] = 'Keep-Alive'
                    return resp

                return Msg.success('空文件夹')
        return Msg.failed_dict(400)

    @safety_strategy
    @auth_token()
    def post(self, id=None):
        if id and isinstance(id, int):
            folder = DiskFolder.get_by_id(id)
            if folder:
                path = folder.folder_path + folder.name
                data = DiskFolder.query_group_path_files(path, g.user.id)
                data = list(data)
                if len(data) > 0:
                    return Msg.success('ok')
                return Msg.failed_dict(5002)
        return Msg.failed_dict(400)


class RepeatDelete(Resource):
    l_parse = reqparse.RequestParser()
    l_parse.add_argument('list', required=True, type=dict, action='append')

    @safety_strategy
    @auth_token()
    def post(self):
        arg = self.l_parse.parse_args()
        for item in arg['list']:
            if item.get('type') == 'folder':
                folder = DiskFolder.query_one(id=item.get('id'), user_id=g.user.id)
                if folder:
                    folder.update(is_trash=1)
            elif item.get('type') == 'file':
                file = DiskFile.query_one(id=item.get('id'), user_id=g.user.id)
                if file:
                    file.update(is_trash=1)

        return Msg.success('ok')


api.add_resource(CreateFolder, '/folder/add', endpoint='c_folder')
api.add_resource(UpdateFolder, '/folder/update', endpoint='u_folder')
api.add_resource(DeleteFolder, '/folder/delete', endpoint='d_folder')
api.add_resource(RepeatDelete, '/folder/delete/repeat', endpoint='rd_folder')
api.add_resource(FolderGroupFiles, '/folder/download/<int:id>', endpoint='d_group_files')
api.add_resource(ListPath, '/path', endpoint='listPath')
